package com.chinacoal.hr.levelimpl.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.chinacoal.hr.levelapi.entity.*;
import com.chinacoal.hr.levelimpl.dao.AttendanceAppealDao;
import com.chinacoal.hr.levelimpl.mapper.AttendanceAppealMapper;
import com.chinacoal.hr.levelimpl.service.*;
import com.chinacoal.hr.levelimpl.utils.StaticDicts;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

/**
 * @author: YunTao.Li
 * @create: 2019-11-14 11:35
 * @description: 考勤申诉单service实现
 **/
@Service
public class AttendanceAppealServiceImpl implements AttendanceAppealService {

    @Autowired
    private AttendanceAppealDao attendanceAppealDao;

    @Autowired
    private AttendanceAppealDetailService attendanceAppealDetailService;

    @Autowired
    private TransPaperDetailListService transPaperDetailListService;

    @Autowired
    private FileInfoService fileInfoService;

    @Autowired
    private WorkflowService workflowService;

    public IPage<AttendanceAppeal> getAttendanceAppealList(Map<String, Object> condition) {
        IPage<AttendanceAppeal> attendanceInfoIPage = attendanceAppealDao.getAttendanceAppealList(condition);
        return attendanceInfoIPage;
    }

    /**
     * 根据条件获得考勤申诉信息
     *
     * @param condition :
     * @return : com.chinacoal.hr.levelimpl.entity.AttendanceAppeal
     * @author : YunTao.Li
     * @date : 2019/11/27 2019/11/27
     */
    @Override
    public AttendanceAppeal getAppealByCondition(Map<String, Object> condition) throws Throwable {
        // step1 : 根据查询条件获得考勤申诉信息
        AttendanceAppeal attendanceAppeal = this.attendanceAppealDao.getAttendanceAppeal(condition);
        String explainId = attendanceAppeal.getExplainId();

        // step2 : 获得考勤申诉明细信息
        Map empCondition = new HashMap();
        empCondition.put("explainId", explainId);
        List<AttendanceAppealDetail> attendanceAppealDetails = this.attendanceAppealDetailService.getAttendanceAppealDetailListByAppealId(explainId);

        // 将列表加入考勤申诉实体
        attendanceAppeal.setAttendanceAppealDetailList(attendanceAppealDetails);

        return attendanceAppeal;
    }

    /**
     * 新增考勤申诉，同时新增考勤明细
     *
     * @param record :
     * @return : java.util.Map<java.lang.String,java.lang.String>
     * @author : YunTao.Li
     * @date : 2019/11/21 2019/11/21
     */
    @Transactional
    public Map<String, String> addAttendanceAppeal(AttendanceAppeal record) throws Throwable {
        Map<String, String> result = new HashMap<String, String>();
        result.put("code", "-1");

        try {
            // step1 : 新增考勤申诉记录
            attendanceAppealDao.insertAttendanceAppeal(record);
            String explainId = record.getExplainId();

            // step2 : 循环新增考勤申诉明细记录
            List<AttendanceAppealDetail> detailList = record.getAttendanceAppealDetailList();
            for (int i = 0; i < detailList.size(); i++) {
                AttendanceAppealDetail detailRecord = detailList.get(i);
                detailRecord.setExplainId(explainId);
                detailRecord.setCreationDate(null);
                detailRecord.setLastUpdateDate(null);
                attendanceAppealDetailService.addAttendanceAppealDetail(detailRecord);
            }

            // step3 : 修改相关文件的临时paDocId为正式paDocId
            String realPaDocId = explainId;
            String tempPaDocId = record.getFileParamPaDocId();

            fileInfoService.updatePaDocId(tempPaDocId, realPaDocId);

        } catch (Throwable e) {
            throw e;
        }

        result.put("code", "1");
        return result;
    }

    /**
     * 修改考勤申诉单
     *
     * @param record :
     * @return : java.util.Map<java.lang.String,java.lang.String>
     * @author : YunTao.Li
     * @date : 2019/11/28 2019/11/28
     */
    @Override
    @Transactional
    public Map<String, String> updateAttendanceAppeal(AttendanceAppeal record) throws Throwable {
        Map<String, String> result = new HashMap<String, String>();
        result.put("code", "-1");

        try {
            // step1 : 更新考勤申诉
            this.attendanceAppealDao.updateAttendanceAppeal(record);
            String explainId = record.getExplainId();

            // step2 : 删除考勤申诉明细
            attendanceAppealDetailService.deleteAttendanceAppealDetailByExplainId(explainId);

            // step3 : 重新增加考勤申诉明细
            List<AttendanceAppealDetail> attendanceAppealDetails = record.getAttendanceAppealDetailList();
            for (AttendanceAppealDetail detail : attendanceAppealDetails) {
                detail.setEplDtlId(null);
                this.attendanceAppealDetailService.addAttendanceAppealDetail(detail);
            }
        } catch (Throwable e) {
            throw e;
        }

        result.put("code", "1");
        return result;
    }

    /**
     * 提交考勤申诉
     *
     * @param record :
     * @return : java.util.Map<java.lang.String,java.lang.String>
     * @author : YunTao.Li
     * @date : 2019/11/26 2019/11/26
     */
    @Override
    @Transactional
    public Map<String, String> submitAttendanceAppeal(AttendanceAppeal record) throws Throwable {
        Map<String, String> result = new HashMap<String, String>();
        result.put("code", "-1");

        try {
            String insCode = record.getInsCode();
            String appealID = record.getExplainId();

            // 判断之前有没有创建过流程，还是撤回后再二次提交
            if (StringUtils.isBlank(insCode)) {
                String empName = record.getEmpName();
                String code = record.getExplainCode();
                String processInstTitle = "请审批 " + empName + " 提交的编码为:" + code + "的考勤申诉申请单";

                // step1 : 创建并启动流程，获得processInstID
                String processInstID = workflowService.createAndStartAndFinishFirstWorkitem(WorkflowServiceImpl.PROCESSDEFNAME_APPEAL, processInstTitle, null, appealID, record);
                record.setInsCode(processInstID); //出差申请表，记录流程实例编码
            } else {

                // step1 : 二次提交
                workflowService.createAndStartAndFinishFirstWorkitem(WorkflowServiceImpl.PROCESSDEFNAME_APPEAL, null, insCode, appealID, record);
            }


            // step2 : 修改申诉主表审批状态
            String explainId = record.getExplainId(); //考勤申诉id
            String empId = record.getEmpId();
            String empCode = record.getEmpCode();
            record.setBusinessStatus(StaticDicts.BUSINESS_STATUS_SUBMITTED); // 已提交
            this.attendanceAppealDao.updateAttendanceAppeal(record);

            // step3 : 查询出申诉明细
            List<AttendanceAppealDetail> attendanceAppealDetails = this.attendanceAppealDetailService.getAttendanceAppealDetailListByAppealId(explainId);

            /***
             *  step4 整理申诉日期，如果两条记录一个上午一个下午合并为一个整天
             */
            Map detailSortMap = new HashMap(); //整理后的date：type
            for (int i = 0; i < attendanceAppealDetails.size(); i++) {
                AttendanceAppealDetail detailRecord = attendanceAppealDetails.get(i);
                String attendDate = detailRecord.getAttendDate().toString(); // 申诉日期
                String timeType = detailRecord.getTimeType().toString();// 类型1上午2下午3全天
                if (detailSortMap.containsKey(attendDate)) { //如果有相同的申诉日期，必定是上午或下午
                    detailSortMap.remove(attendDate);
                    detailSortMap.put(attendDate, StaticDicts.TIME_TYPE_ALLDAY);
                } else {
                    detailSortMap.put(attendDate, timeType);
                }
            }

            // step5 : 新增员工事务单汇总表，明细中如果既有上午又有下午则按一整天算
            Set<AttendanceAppealDetail> paperDetailListSet = new HashSet();
            for (int k = 0; k < attendanceAppealDetails.size(); k++) {
                AttendanceAppealDetail detailRecord = attendanceAppealDetails.get(k);
                String attendDate = detailRecord.getAttendDate().toString(); // 申诉日期
                String timeType = detailSortMap.get(attendDate).toString();
                detailRecord.setTimeType(timeType);
                paperDetailListSet.add(detailRecord);
            }

            // step6 : 遍历set插入汇总表
            for (AttendanceAppealDetail appealDetail : paperDetailListSet) {
                Date attendDate = appealDetail.getAttendDate();
                String timeType = appealDetail.getTimeType();

                TransPaperDetailList transPaperDetailListRecord = new TransPaperDetailList();
                transPaperDetailListRecord.setDocTypeId("appeal-xxxxxxxxxxxx"); //TODO:此处应该放申请单类型id
                transPaperDetailListRecord.setPaDocId(explainId);
                transPaperDetailListRecord.setEmpId(empId);
                transPaperDetailListRecord.setEmpCode(empCode);
                transPaperDetailListRecord.setPaDate(attendDate);
                transPaperDetailListRecord.setTimeType(timeType);
                transPaperDetailListRecord.setPaType(StaticDicts.PATYPE_APPEAL);
                transPaperDetailListRecord.setBusinessStatus(StaticDicts.BUSINESS_STATUS_SUBMITTED); // 审批状态：已提交
                transPaperDetailListRecord.setEffectFlag(StaticDicts.EFFECTFLAG_VALID);

                transPaperDetailListService.insertTransPaperDetailList(transPaperDetailListRecord);
            }
        } catch (Throwable e) {
            throw e;
        }

        result.put("code", "1");
        return result;
    }

    /**
     * 撤回考勤申诉
     *
     * @param appeal :
     * @return : java.util.Map<java.lang.String,java.lang.String>
     * @author : YunTao.Li
     * @date : 2019/12/12 2019/12/12
     */
    @Override
    @Transactional
    public Map<String, String> drawbackAttendanceAppeal(AttendanceAppeal appeal) throws Throwable {

        Map<String, String> result = new HashMap<String, String>();
        result.put("code", "-1");

        try {
            // step1 : 完成工作项,撤回
            String processInstID = appeal.getInsCode();
            String explainId = appeal.getExplainId();
            String approvalContext = "测试出差审批意见：撤回";
            workflowService.finishWorkitem(Long.parseLong(processInstID), 0, approvalContext, WorkflowServiceImpl.WORKITEM_OPCODE_DRAWBACK);

            //step3 : 修改出差申请单xip_hr_biz_travel的审批状态BUSINESS_STATUS为B已撤回
            appeal.setBusinessStatus(StaticDicts.BUSINESS_STATUS_DRAWBACK);
            this.attendanceAppealDao.updateAttendanceAppeal(appeal);

            //step4 : 删除xip_hr_pa_list员工事务单汇总表的数据
            transPaperDetailListService.deleteTransPaperDetailListByDocId(explainId);
        } catch (Throwable e) {
            e.printStackTrace();
            throw e;
        }

        result.put("code", "1");
        return result;
    }

    /**
     * 删除考勤申诉信息
     * 包括考勤申诉信息、考勤申诉明细、事务单汇总
     *
     * @param explainId :
     * @return : java.util.Map<java.lang.String,java.lang.String>
     * @author : YunTao.Li
     * @date : 2019/11/26 2019/11/26
     */
    @Override
    public Map<String, String> deleteAttendanceAppeal(String explainId) throws Throwable {
        Map<String, String> result = new HashMap<String, String>();
        result.put("code", "-1");
        try {
            // step1 : 删除考勤申诉明细(外键先删)
            this.attendanceAppealDetailService.deleteAttendanceAppealDetailByExplainId(explainId);

            // step2 : 删除考勤申诉信息
            this.attendanceAppealDao.deleteAttendanceAppealById(explainId);

            //TODO:删除员工事务单汇总表（软删除)
            // step3 : 删除员工事务单汇总表（软删除)
        } catch (Throwable e) {
            throw e;
        }

        result.put("code", "1");
        return result;

    }
}
